package com.hds.modules.app.controller;

import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.hds.common.exception.RRException;
import com.hds.common.utils.ValidateUtils;
import com.hds.common.validator.Assert;
import com.hds.modules.app.annotation.Login;
import com.hds.modules.app.annotation.LoginUser;
import com.hds.modules.app.utils.HdsUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.hds.common.contstant.WechatConstant;
import com.hds.common.utils.HttpUtils;
import com.hds.modules.app.entity.UserEntity;
import com.hds.modules.app.service.UserService;
import com.hds.modules.app.utils.WechatUtils;
import com.hds.modules.sys.controller.AbstractController;


/**
 * ClassName WechatController
 * @Function TODO 
 * @date 2017年12月6日
 */
@RestController
@RequestMapping("/app/wechat")
public class WechatController extends AbstractController {
	@Autowired
	WechatUtils wechatUtils;

	@Autowired
	HdsUtils hdsUtils;
	
	@Autowired
    private UserService userService;
	
	
	/**
	 * 微信授权登录
	 * @param req
	 * @throws IOException 
	 * @throws ParseException 
	 */
	@Login
	@SuppressWarnings("deprecation")
	@GetMapping("auth")
	public void wxLogin(@LoginUser UserEntity user, HttpServletRequest req, HttpServletResponse response, String redirect) throws ParseException, IOException{
		String userId="", openid="";
		logger.info("user:{}",user);
		String mobile = user.getMobile();
		if(ValidateUtils.phoneReg(mobile)){
			userId = String.valueOf(user.getUserId());

			openid = user.getOpenid();
			if(!StringUtils.isBlank(openid)){
				String redrectUrl = redirect;
				response.sendRedirect(redrectUrl);
				return;
			}

		}else return;

		redirect=hdsUtils.getDomainFront(); //跳转到前端页面
		String authCallBack = hdsUtils.getDomain() + "/hds/app/wechat/callback?userId="+userId+"&redirect="+redirect;
		System.out.println("auth="+authCallBack);
		String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+wechatUtils.getAppId()
				+ "&redirect_uri="+URLEncoder.encode(authCallBack)
				+ "&response_type=code"
				+ "&scope=snsapi_base" //snsapi_userinfo, snsapi_base
				+ "&state=STATE#wechat_redirect";

		response.sendRedirect(url);
	}
	
	/**
	 * 微信授权回调-获取用户基本信息
	 * @param req
	 * @throws IOException 
	 * @throws ParseException 
	 */
	@GetMapping("callback")
	public void wxAuthCallback(HttpServletRequest req, HttpServletResponse resp) throws ParseException, IOException{
		String code = req.getParameter("code");
		String userId = req.getParameter("userId");
		String redirect = req.getParameter("redirect");
		System.out.println("code="+code); //注意这块code不要重复请求，否则会报40029错误
		
		String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+wechatUtils.getAppId()
		+ "&secret="+wechatUtils.getAppSecret()
		+ "&code="+code
		+ "&grant_type=authorization_code";
		
		String avatar = ""; //头像
		String nickName = ""; //昵称
		String wx_access_token = "";
		
		if(StringUtils.isEmpty(code)){
			try {
				JSONObject jsonObject = HttpUtils.doGetStr(url);
				System.out.println("jsonObject="+jsonObject);
				String token = jsonObject.getString("access_token");
				String openid = jsonObject.getString("openid");
				String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token="+token
						+ "&openid="+openid
						+ "&lang=zh_CN";
				JSONObject jsonUserInfo = HttpUtils.doGetStr(getUserInfoUrl);
				//user.setOpenid(jsonUserInfo.getString("openid"));
			} catch (ParseException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}else{
			String currOpenId="";
			String baseUrl = WechatConstant.OAUTH2_GET_ACCESS_TOKEN;
			baseUrl = baseUrl.replace("APPID", wechatUtils.getAppId())
					.replace("SECRET",wechatUtils.getAppSecret())
					.replace("CODE", code);
			
			JSONObject jsonObject = HttpUtils.doGetStr(baseUrl);
			if (null != jsonObject){
				if (jsonObject.containsKey("openid")){
					currOpenId = jsonObject.getString("openid");
				}
				if(jsonObject.containsKey("access_token")){
					wx_access_token = jsonObject.getString("access_token");
				}
				//获取接口调用凭证
				String apiAccessToken = getApiAccessToken(wechatUtils.getAppId(), wechatUtils.getAppSecret()); 
				
				String userInfoUrl = WechatConstant.GET_USER_BASE_INFO;
				JSONObject userInfoObj = null;
				if(apiAccessToken!=null){
					userInfoUrl = userInfoUrl
							.replace("ACCESS_TOKEN", apiAccessToken)
							.replace("OPENID", currOpenId);
					userInfoObj = HttpUtils.doGetStr(userInfoUrl);
				}else{
					throw new RRException("微信授权失败，请联系客服人员。");
				}
				
				logger.info("weixin user info...{}",userInfoObj.toString());
				UserEntity currentUser = userService.selectById(Long.valueOf(userId));
				if(userId!=null){
					currentUser.setOpenid(currOpenId);
					if(userInfoObj.getString("nickname") != null){currentUser.setNickName(userInfoObj.getString("nickname"));}
					if(userInfoObj.getString("headimgurl") != null){currentUser.setAvatar(userInfoObj.getString("headimgurl"));}
					userService.updateById(currentUser);
				}
				resp.sendRedirect(redirect);
				
		}
	  }
    }
	
	/**
	 * 获取接口微信调用凭证access_token
	 * @param appid
	 * @param appSecret
	 * @return
	 * @throws ParseException
	 * @throws IOException
	 */
	public String getApiAccessToken(String appid, String appSecret) throws ParseException, IOException{
		String apiAccessToken = WechatConstant.API_ACCESS_TOKEN;
		String apiAccessTokenBaseUrl = apiAccessToken.replace("APPID", appid).replace("APPSECRET", appSecret);
		
		JSONObject apiAccessTokenObject = HttpUtils.doGetStr(apiAccessTokenBaseUrl);
		logger.info("apiAccessTokenObject...{}",apiAccessTokenObject.toString());
		String access_token = null;
		if(apiAccessTokenObject!=null){
			access_token = apiAccessTokenObject.getString("access_token");
		}
		return access_token;
	}
	
	
	public static UserEntity setUserInfo(JSONObject jsonObject){
		String nickName="",avatar="",openid="";
		if(jsonObject.containsKey("nickname")) nickName = jsonObject.getString("nickname");
		if(jsonObject.containsKey("avatar")) avatar = jsonObject.getString("headimgurl");
		if(jsonObject.containsKey("openid")) openid = jsonObject.getString("openid");
		
		UserEntity user=new UserEntity(); 
		user.setAvatar(avatar);
		user.setNickName(nickName);
		user.setOpenid(openid);
		return user;
	}
	
}
